package com.xinyu.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinyu.domain.User;
import com.xinyu.domain.UserSite;
import com.xinyu.vo.LessonPermissionDecision;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@Service
public class LessonPermissionEvaluator {

    private final IUserService userService;
    private final IUserSiteService userSiteService;

    public LessonPermissionEvaluator(IUserService userService, IUserSiteService userSiteService) {
        this.userService = userService;
        this.userSiteService = userSiteService;
    }

    public LessonPermissionContext buildContext(Integer requesterId) {
        if (requesterId == null) {
            return LessonPermissionContext.anonymous();
        }
        User requester = userService.getById(requesterId);
        if (requester == null) {
            return LessonPermissionContext.missing();
        }
        return new LessonPermissionContext(requester, false, loadSiteIds(requesterId));
    }

    public LessonPermissionContext buildContext(User requester) {
        if (requester == null || requester.getId() == null) {
            return LessonPermissionContext.anonymous();
        }
        return new LessonPermissionContext(requester, false, loadSiteIds(requester.getId()));
    }

    public LessonPermissionDecision evaluate(Integer ownerId, User owner, LessonPermissionContext context) {
        LessonPermissionContext safeContext = context == null ? LessonPermissionContext.anonymous() : context;
        Integer resolvedOwnerId = ownerId;
        if (resolvedOwnerId == null && owner != null) {
            resolvedOwnerId = owner.getId();
        }
        if (resolvedOwnerId == null) {
            return LessonPermissionDecision.deny("文档缺少发布者信息，请联系管理员");
        }
        if (safeContext.isAnonymous()) {
            return LessonPermissionDecision.deny("请登录后再下载该文档");
        }
        if (safeContext.isUserMissing()) {
            return LessonPermissionDecision.deny("账号不存在或已被禁用，请重新登录");
        }
        User requester = safeContext.getRequester();
        if (requester == null) {
            return LessonPermissionDecision.deny("请登录后再下载该文档");
        }
        if (Objects.equals(resolvedOwnerId, requester.getId()) || isAdmin(requester)) {
            return LessonPermissionDecision.allow();
        }
        User resolvedOwner = owner;
        if (resolvedOwner == null) {
            resolvedOwner = userService.getById(resolvedOwnerId);
        }
        if (resolvedOwner == null) {
            return LessonPermissionDecision.deny("文档发布者不存在，请联系管理员");
        }
        Set<Integer> ownerSites = loadSiteIds(resolvedOwnerId);
        Set<Integer> requesterSites = safeContext.getSiteIds();
        if (!ownerSites.isEmpty() && !requesterSites.isEmpty()) {
            Set<Integer> intersection = new HashSet<>(requesterSites);
            intersection.retainAll(ownerSites);
            if (!intersection.isEmpty()) {
                return LessonPermissionDecision.allow();
            }
        }
        return LessonPermissionDecision.deny("仅限同站点成员或管理员下载该文档");
    }

    private boolean isAdmin(User user) {
        return (user.getIsAdmin() != null && user.getIsAdmin() == 1)
                || (user.getRole() != null && user.getRole() == 1);
    }

    private Set<Integer> loadSiteIds(Integer userId) {
        if (userId == null) {
            return Collections.emptySet();
        }
        List<UserSite> relations = userSiteService.list(new LambdaQueryWrapper<UserSite>().eq(UserSite::getUserId, userId));
        if (relations == null || relations.isEmpty()) {
            return Collections.emptySet();
        }
        Set<Integer> siteIds = new HashSet<>();
        for (UserSite relation : relations) {
            if (relation != null && relation.getSiteId() != null) {
                siteIds.add(relation.getSiteId());
            }
        }
        return siteIds;
    }

    public static class LessonPermissionContext {
        private final User requester;
        private final boolean userMissing;
        private final Set<Integer> siteIds;

        private LessonPermissionContext(User requester, boolean userMissing, Set<Integer> siteIds) {
            this.requester = requester;
            this.userMissing = userMissing;
            this.siteIds = siteIds == null ? Collections.emptySet() : Collections.unmodifiableSet(siteIds);
        }

        public static LessonPermissionContext anonymous() {
            return new LessonPermissionContext(null, false, Collections.emptySet());
        }

        public static LessonPermissionContext missing() {
            return new LessonPermissionContext(null, true, Collections.emptySet());
        }

        public User getRequester() {
            return requester;
        }

        public boolean isAnonymous() {
            return requester == null && !userMissing;
        }

        public boolean isUserMissing() {
            return userMissing;
        }

        public Set<Integer> getSiteIds() {
            return siteIds;
        }
    }
}
